package com.snatch.snatchnd.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import com.snatch.common.constant.SnatchConstant;
import com.snatch.common.vo.LoginAccount;
import com.snatch.common.vo.WebConfig;
import com.snatch.common.vo.WebInfo;
import com.snatch.common.vo.WebUrl;
import com.snatch.snatchnd.service.AccountService;
import com.snatch.snatchnd.system.AccountData;
import com.snatch.snatchnd.system.SystemData;
import com.snatch.work.service.SnatchControl;
import com.snatch.work.service.SnatchService;
import com.snatch.work.vo.LoginData;
import com.snatch.work.vo.ThirdInfo;

@Service
public class AccountServiceImpl implements AccountService{
	
	ConcurrentMap<String, Login> loginThreds = new ConcurrentHashMap<String, Login>();// 每个登录线程的名字和线程ID
	
	protected Logger log = Logger.getLogger(AccountServiceImpl.class);
	
	
	SnatchService hgSnatchDataImpl;
	
	long sleepTiem = 35*1000;
	
	@Override
	public int loginAccount(String webCode) {
		WebConfig webConfig = SystemData.findWebConfig(webCode);
		if(webConfig!=null){
			if(!loginThreds.containsKey(webConfig.getWebCode())){
				Login login = new Login(webCode);
				new Thread(login).start();
				loginThreds.put(webConfig.getWebCode(), login);
			}
		}
		return SnatchConstant.SUCCESS;
	}
	
	@Override
	public boolean webValid(String webCode) {
		return loginThreds.containsKey(webCode);
	}

	
	private List<LoginData> foundLoginData(WebConfig webConfig){
		String webCode = webConfig.getWebCode();
		List<LoginData> list = new ArrayList<LoginData>();
		List<LoginAccount> acclist = webConfig.getLoginAccounts();
		for(LoginAccount loginAccount : acclist){
			if(notHaveData(webCode,loginAccount.getUserName())){
				LoginData loginData = new LoginData();
				loginData.setLogin(false);
				loginData.setOnlyCode(webCode);
				/**
				 * 代理 url 权重
				 */
				if(webConfig.getProxys().size()>0){
					if(webConfig.getProxys().size()==1){
						loginData.setProxy(webConfig.getProxys().get(0));
					}else{
						loginData.setProxy(webConfig.getProxys().get(new Random().nextInt(webConfig.getProxys().size()-1)));
					}
				}
				WebInfo webInfo = new WebInfo();
				/**
				 * 设置url权重
				 */
				WebUrl webUrl = null;
				if(webConfig.getWebUrls().size()==1){
					webUrl = webConfig.getWebUrls().get(0);
				}else{
					webUrl = webConfig.getWebUrls().get(new Random().nextInt(webConfig.getWebUrls().size()-1));
				}
				webInfo.setUrl(webUrl.getUrl());
				webInfo.setSnatchWeb(webConfig.getWebCode());
				webInfo.setReadTimeOut(webConfig.getReadTimeOut());
				webInfo.setConnectionTimeOut(webConfig.getConnectionTimeOut());
				webInfo.setLangx(webConfig.getLangx());
				loginData.setWebConfig(webInfo);
				loginData.setLoginAccount(loginAccount);
				list.add(loginData);
			}
			
		}
		return list;
	}
	
	/**
	 * 不存在数据
	 * @param web
	 * @param username
	 * @return
	 */
	private boolean notHaveData(String webCode,String username){
		CopyOnWriteArrayList<LoginData> list = AccountData.loginDatas.get(webCode);
		if(null == list){
			return true;
		}
		for(LoginData loginData : list){
			if(loginData.getLoginAccount().getUserName().equals(username)){
				return false;
			}
		}
		return true;
	}
	
	
	

	
	
	
	private class Login implements Runnable{
		String webCode;
		private boolean flag = true;
		
		public Login(String webCode){
			this.webCode = webCode;
		}
		
		private void initLoginData(){
			WebConfig webConfig = SystemData.findWebConfig(webCode);
			List<LoginData> list = foundLoginData(webConfig);
			for(LoginData loginData : list){
				AccountData.addLoginData(webConfig.getWebCode(),loginData);
			}
		}
		public void destroyLoginThread(){
			flag = false;
		}
		@Override
		public void run() {
			while (flag) {
				try {
					hgSnatchDataImpl = SnatchControl.getSnatchService(webCode);
					initLoginData();
					List<LoginData> list = AccountData.loginDatas.get(webCode);
						for(LoginData loginData : list){
							if(!loginData.isLogin()){
								if(loginData.getTryNum()<4){
									ThirdInfo thirdInfo ;
									log.info("标识ID："+loginData.getWebConfig().getSnatchWeb()+" 帐号："+loginData.getLoginAccount().getUserName()+" 开始登录！");
									try {
										thirdInfo = (ThirdInfo) hgSnatchDataImpl.connectionWeb(loginData);
										loginData.addTryNum();
										if(null == thirdInfo){
											log.info("标识ID："+loginData.getWebConfig().getSnatchWeb()+" 帐号："+loginData.getLoginAccount().getUserName()+" 获取第三方对象失败!");
											continue;
										}
										boolean refreshRet = hgSnatchDataImpl.refreshValidateCode(thirdInfo);
										int tryNum = 1;
										while (!refreshRet && tryNum<5 ) {
											log.info("标识ID："+loginData.getWebConfig().getSnatchWeb()+" 帐号："+loginData.getLoginAccount().getUserName()+"刷新验证码失败,重试... " + tryNum);
											refreshRet = hgSnatchDataImpl.refreshValidateCode(thirdInfo);
											tryNum++;
										}
										int loginStatus = hgSnatchDataImpl.login(thirdInfo);// 登录
										if (loginStatus == SnatchConstant.SUCCESS) {// 登录成功
											loginData.setTryNum(0);
											loginData.setLogin(true);
											AccountData.addThirdInfo(webCode,thirdInfo);
											SystemData.systemType.remove(webCode);
											log.info("标识ID："+loginData.getWebConfig().getSnatchWeb()+" 帐号："+loginData.getLoginAccount().getUserName()+" 登录成功!");
										}  else if (loginStatus == SnatchConstant.LOGIN_FAIL_WRONG_USERNAME_OR_PASSWORD) {// 用户名或密码错误
											log.info("标识ID："+loginData.getWebConfig().getSnatchWeb()+" 帐号："+loginData.getLoginAccount().getUserName()+" 登录失败,用户名【" + loginData.getLoginAccount().getUserName() + "】或密码【" +  loginData.getLoginAccount().getUserPwd() + "】错误!");
										} else if (loginStatus == SnatchConstant.LOGIN_FAIL_SYSTEM_MAINTENANCE) {// 系统维护
											log.info("标识ID："+loginData.getWebConfig().getSnatchWeb()+" 帐号："+loginData.getLoginAccount().getUserName()+ "登录失败,系统正在维护中......");
											loginData.setTryNum(0);
											SystemData.systemType.put(webCode, "系统正在维护中...");
											break;
										} else if (loginStatus == SnatchConstant.LOGIN_FAIL_CHANGE_PASSWORD) {// 变更密码
											log.info("标识ID："+loginData.getWebConfig().getSnatchWeb()+" 帐号："+loginData.getLoginAccount().getUserName()+ "【" + loginData.getLoginAccount().getUserName() + "】登录失败,该密码【" + loginData.getLoginAccount().getUserPwd()
													+ "】久未变更,为了安全起见,请先变更密码后再继续使用!");
										} else if (SnatchConstant.LOGIN_FAIL_ACCOUNT_LOCKED == loginStatus) {
											log.info("标识ID："+loginData.getWebConfig().getSnatchWeb()+" 帐号："+loginData.getLoginAccount().getUserName()+ "登录时,帐号已关闭");
										} else if (SnatchConstant.LOGIN_FAIL_WRONG_VC == loginStatus) {
											log.info("标识ID："+loginData.getWebConfig().getSnatchWeb()+" 帐号："+loginData.getLoginAccount().getUserName()+ "登录时验证码错误");
										} else {
											log.info("标识ID："+loginData.getWebConfig().getSnatchWeb()+" 帐号："+loginData.getLoginAccount().getUserName()+ "登录失败,错误码："+loginStatus);
										}
										
									} catch (Exception e) {
										e.printStackTrace();
										log.error("标识ID："+loginData.getWebConfig().getSnatchWeb()+" 帐号："+loginData.getLoginAccount().getUserName()+" 登录时报错");
									}
								}else{
									log.info("标识ID："+loginData.getWebConfig().getSnatchWeb()+" 帐号："+loginData.getLoginAccount().getUserName()+ "尝试次数太多!");
								}
						}
						
					}
						Thread.sleep(sleepTiem);
				} catch (Exception e) {
					log.error(e);
				}
			}
				
		}
		
		
		
	}



	







}
